package cn.wolfcode.cms.service.impl;

import cn.wolfcode.cms.domain.*;
import cn.wolfcode.cms.mapper.OrderBillItemMapper;
import cn.wolfcode.cms.mapper.OrderBillMapper;
import cn.wolfcode.cms.mapper.ProductMapper;
import cn.wolfcode.cms.mapper.StockMapper;
import cn.wolfcode.cms.query.QueryObject;
import cn.wolfcode.cms.service.IOrderBillService;
import cn.wolfcode.cms.util.PageResult;
import com.alibaba.druid.pool.vendor.SybaseExceptionSorter;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

@Service
public class OrderBillServiceImpl implements IOrderBillService {

    @Autowired
    private OrderBillMapper orderBillMapper;

    @Autowired
    private OrderBillItemMapper orderBillItemMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private ProductMapper productMapper;

    public void save(OrderBill entity) {
        saveEntity(entity);

    }

    // 保存实例
    public void saveEntity(OrderBill entity) {
        // 获得明细集合
        List<OrderBillItem> items = entity.getItems();
        //判断明细集合是否存在
        if (items != null && items.size() > 0) {
            // 只在不为空的情况下才进行添加操作
            // 1.设置初始订单状态 --> 未审核
            entity.setStatus(0);
            // 2 设置录入人
            entity.setInputUser((Employee) SecurityUtils.getSubject().getPrincipal());
            // 3.设置录入时间
            entity.setInputTime(new Date());
            // 4.迭代明细集合计算金额小计与number
            BigDecimal totalNumber = new BigDecimal("0");
            BigDecimal totalAmount = new BigDecimal("0");
            for (OrderBillItem item : items) {
                // 5.统计总数
                totalNumber = totalNumber.add(item.getNumber());
                // 6.金额小计
                BigDecimal amount = item.getNumber().multiply(item.getProduct().getCostPrice())
                        .setScale(2, RoundingMode.HALF_UP);
                totalAmount = totalAmount.add(amount);
                // 将小计金额和数量设置回对象中
                entity.setTotalAmount(totalAmount);
                entity.setTotalNumber(totalNumber);
                // 7.同时将小计金额设置到明细表中
                item.setAmount(amount);
            }
            // 迭代完成后,先添加主订单后添加明细,明细的添加需要bill的id
            orderBillMapper.insert(entity);
            for (OrderBillItem item : items) {
                // 先获取id,在添加
                item.setBillId(entity.getId());
                orderBillItemMapper.insert(item);
            }
        }
    }

    public void update(OrderBill entity) {
        updateEntity(entity);
    }

    public void updateEntity(OrderBill entity) {

        //为防止明细重复,先将原有的明细删除,再进行添加
        orderBillItemMapper.deleteByBillId(entity.getId());
        // 先设置基本数据
        // 修改时间
        entity.setInputTime(new Date());
        // 修改人
        entity.setInputUser((Employee) SecurityUtils.getSubject().getPrincipal());
        //如果有明细,重新计算amount和number
        List<OrderBillItem> items = entity.getItems();
        //判断明细集合是否存在
        if (items != null && items.size() > 0) {
            // 只在不为空的情况下才进行添加操作
            // 1.设置初始订单状态 --> 未审核
            entity.setStatus(0);
            // 4.迭代明细集合计算金额小计与number
            BigDecimal totalNumber = new BigDecimal("0");
            BigDecimal totalAmount = new BigDecimal("0");
            for (OrderBillItem item : items) {
                // 5.统计总数
                totalNumber = totalNumber.add(item.getNumber());
                // 6.金额小计
                BigDecimal amount = item.getNumber().multiply(item.getProduct().getCostPrice())
                        .setScale(2, RoundingMode.HALF_UP);
                totalAmount = totalAmount.add(amount);
                // 将小计金额和数量设置回对象中
                entity.setTotalAmount(totalAmount);
                entity.setTotalNumber(totalNumber);
                // 7.同时将小计金额设置到明细表中
                item.setAmount(amount);
            }
            // 迭代完成后,先添加主订单后添加明细,明细的添加需要bill的id
            orderBillMapper.updateByPrimaryKey(entity);
            for (OrderBillItem item : items) {
                // 先获取id,在添加
                item.setBillId(entity.getId());
                orderBillItemMapper.insert(item);
            }
        }
    }

    public void delete(Long id) {
        // 删除订单之前将对应的明细也删除
        orderBillItemMapper.deleteByBillId(id);
        orderBillMapper.deleteByPrimaryKey(id);
    }

    public OrderBill get(Long id) {
        return orderBillMapper.selectByPrimaryKey(id);
    }


    public List<OrderBill> list() {
        return orderBillMapper.selectAll();
    }

    public Object query(QueryObject qo) {
        //查总数
        int total = orderBillMapper.queryForCount(qo);
        if (total == 0) {
            return new PageResult();
        }
        //查数据
        List<OrderBill> rows = orderBillMapper.queryForList(qo);
        return new PageResult(total, rows);
    }

    // 订单审核
    public void audit(Long id) {
        // 需要修改的有/审核人/审核时间/订单状态
        //1.先根据id查询订单的审核情况
        OrderBill orderBill = orderBillMapper.selectByPrimaryKey(id);
        if (orderBill.getStatus() == OrderBill.AUDIT) {
            throw new RuntimeException("订单已审核!不可操作");
        }
        // 2.如果没有审核就继续
        orderBill.setStatus(OrderBill.AUDIT);
        // 3.设置审核时间
        orderBill.setAuditTime(new Date());
        // 4.设置审核人
        Employee currentUser = (Employee) SecurityUtils.getSubject().getPrincipal();
        orderBill.setAuditor(currentUser);
        // 5真正的业务操作
        orderBillMapper.audit(orderBill);

        // 6对于盘点表进行数据更新
        List<OrderBillItem> items = orderBill.getItems();
        if (items!=null && items.size()>0){
            // 如果明细不为空就对盘点表进行更新
            Stock stock = new Stock();
            for (OrderBillItem item : items) {
                // 先判断当前迭代的商品是否已经存在与库中
                Stock currentStock  = stockMapper.getProductByItem(item.getProduct().getName());

                if (currentStock==null){
                    // 如果不存在就添加
                    //根据productName来查询商品的信息
                    Product currentProduct = productMapper.getProductByName(item.getProduct().getName());
                    // 然后将商品对应的信息设置到盘点对象中添加到盘点表中
                    // 设置商品类别
                    stock.setProductFirstlevel(currentProduct.getFirstLevel());
                    //设置商品名称
                    stock.setProductName(currentProduct.getName());
                    // 设置类别
                    stock.setProductSpecification(currentProduct.getSpecification());
                    stock.setStockNumber(item.getNumber());
                    // 设置盘点人
                    stock.setStockUser(currentUser);
                    // 设置盘点时间
                    stock.setStockTime(new Date());
                    // 真正的业务操作
                    stockMapper.insert(stock);
                } else{

                    // 如果存在就更新 (数量 stockNumber/ 盘点时间stockTime/)
                    // 先按商品名称查询查原来多少商品,在加这次的存入量
                    BigDecimal totalNumber = currentStock.getStockNumber().add(item.getNumber());
                    System.out.println("当前库存数量"+currentStock.getStockNumber());
                    System.out.println("新入库数量"+item.getNumber());
                    System.out.println("----------------------总数量"+totalNumber);
                    // 将最新的数量重新设置回库存盘点对象中
                    currentStock.setStockNumber(totalNumber);
                    // 设置盘点人
                    currentStock.setStockUser(currentUser);
                    // 设置盘点时间
                    currentStock.setStockTime(new Date());
                    stockMapper.newUpdateByPrimaryKey(currentStock);
                }
            }

        }

    }

    public List<OrderBillItem> getItemsByBillId(Long id) {

        return orderBillItemMapper.getItemsByBillId(id);
    }

}
